using System;
using System.Globalization;
using System.Web.UI;
using System.Web.UI.WebControls.Adapters;
using System.Web.UI.WebControls;
using System.Reflection;
using System.Web;

namespace Be.Timvw.Framework.Web.UI.Adapters
{
    public class LinkButtonAdapter : WebControlAdapter
    {
        public static string ClickedParameterName
        {
            get { return "LinkButton"; }
        }

        protected override void OnPreRender(EventArgs e)
        {
            base.OnPreRender(e);
            this.RaiseEventsWhenLinkButtonClicked();
        }

        protected virtual void RaiseEventsWhenLinkButtonClicked()
        {
            LinkButton linkButton = Control as LinkButton;
            if (linkButton == null) return;

            HttpContext httpContext = HttpContext.Current;
            if (httpContext == null) return;

            HttpRequest httpRequest = httpContext.Request;
            if (httpRequest == null) return;

            string clickedParameter = httpRequest.QueryString[ClickedParameterName];
            if (clickedParameter == null) return;

            if (clickedParameter != linkButton.UniqueID) return;

            this.RaiseEvents(linkButton);
        }

        protected virtual void RaiseEvents(LinkButton linkButton)
        {
            this.RaiseClickedEvent(linkButton);
            this.RaiseCommandEvent(linkButton);
        }

        protected virtual MethodInfo GetLinkButtonPrivateInstanceMethodInfo(string methodName)
        {
            return typeof(LinkButton).GetMethod(methodName, BindingFlags.Instance | BindingFlags.NonPublic);
        }

        protected virtual void RaiseClickedEvent(LinkButton linkButton)
        {
            MethodInfo onClickMethodInfo = this.GetLinkButtonPrivateInstanceMethodInfo("OnClick");
            if (onClickMethodInfo == null) return;

            onClickMethodInfo.Invoke(linkButton, new object[] { EventArgs.Empty });
        }

        protected virtual void RaiseCommandEvent(LinkButton linkButton)
        {
            MethodInfo onCommandMethodInfo = this.GetLinkButtonPrivateInstanceMethodInfo("OnCommand");
            if (onCommandMethodInfo == null) return;

            CommandEventArgs args = new CommandEventArgs(linkButton.CommandName, linkButton.CommandArgument);
            onCommandMethodInfo.Invoke(linkButton, new object[] { args });
        }

        protected override void RenderBeginTag(HtmlTextWriter writer)
        {
            LinkButton ctrl = Control as LinkButton;
            if (ctrl == null) return;

            writer.AddAttribute(HtmlTextWriterAttribute.Href, string.Format("{0}{1}={2}", UriHelper.QuerySeparator, ClickedParameterName, ctrl.UniqueID));

            if (ctrl.ID != null)
            {
                writer.AddAttribute(HtmlTextWriterAttribute.Id, ctrl.ClientID);
            }

            string accessKey = ctrl.AccessKey;
            if (accessKey.Length > 0)
            {
                writer.AddAttribute(HtmlTextWriterAttribute.Accesskey, accessKey);
            }

            if (!ctrl.Enabled)
            {
                writer.AddAttribute(HtmlTextWriterAttribute.Disabled, "disabled");
            }

            int tabIndex = ctrl.TabIndex;
            if (tabIndex != 0)
            {
                writer.AddAttribute(HtmlTextWriterAttribute.Tabindex, tabIndex.ToString(NumberFormatInfo.InvariantInfo));
            }

            string toolTip = ctrl.ToolTip;
            if (toolTip.Length > 0)
            {
                writer.AddAttribute(HtmlTextWriterAttribute.Title, toolTip);
            }

            if (ctrl.ControlStyleCreated && !ctrl.ControlStyle.IsEmpty)
            {
                ctrl.ControlStyle.AddAttributesToRender(writer, ctrl);
            }

            writer.RenderBeginTag(HtmlTextWriterTag.A);
        }
    }
}
